﻿using System.Text;
using System.Text.Json;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using System.Text.Json.Nodes;

namespace CooJson
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        private JsonNode? _currentJsonNode;

        public MainWindow()
        {
            InitializeComponent();
            
            // Set up context menu for TreeView items
            JsonTreeView.ContextMenuOpening += JsonTreeView_ContextMenuOpening;
            
            // Set up text changed event for real-time updates
            InputTextBox.TextChanged += InputTextBox_TextChanged;
        }

        // Search functionality
        private List<TreeViewItem> _searchResults = new List<TreeViewItem>();
        private int _currentSearchIndex = -1;
        
        private void Window_KeyDown(object sender, KeyEventArgs e)
        {
            // Ctrl+F to open search
            if (e.Key == Key.F && Keyboard.Modifiers == ModifierKeys.Control)
            {
                ShowSearchPanel();
                e.Handled = true;
            }
            // Escape to close search
            else if (e.Key == Key.Escape && SearchPanel.Visibility == Visibility.Visible)
            {
                CloseSearchPanel();
                e.Handled = true;
            }
        }
        
        private void SearchButton_Click(object sender, RoutedEventArgs e)
        {
            ShowSearchPanel();
        }
        
        private void ShowSearchPanel()
        {
            SearchPanel.Visibility = Visibility.Visible;
            SearchTextBox.Focus();
            SearchTextBox.SelectAll();
        }
        
        private void CloseSearchPanel()
        {
            SearchPanel.Visibility = Visibility.Collapsed;
            ClearSearchHighlights();
        }
        
        private void CloseSearchButton_Click(object sender, RoutedEventArgs e)
        {
            CloseSearchPanel();
        }
        
        private void SearchTextBox_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.Key == Key.Enter)
            {
                PerformSearch();
                e.Handled = true;
            }
        }
        
        private void FindNextButton_Click(object sender, RoutedEventArgs e)
        {
            FindNext();
        }
        
        private void FindPrevButton_Click(object sender, RoutedEventArgs e)
        {
            FindPrevious();
        }
        
        private void JsonTreeView_ContextMenuOpening(object sender, ContextMenuEventArgs e)
        {
            // Only show context menu when an item is selected
            if (JsonTreeView.SelectedItem == null)
            {
                e.Handled = true; // Prevent context menu from showing
            }
        }
        
        // Debounce timer to prevent excessive updates
        private System.Timers.Timer? _debounceTimer;
        
        private void InputTextBox_TextChanged(object sender, TextChangedEventArgs e)
        {
            // Reset and restart the timer on each text change
            if (_debounceTimer == null)
            {
                _debounceTimer = new System.Timers.Timer(500); // 500ms delay
                _debounceTimer.Elapsed += (s, args) =>
                {
                    Dispatcher.Invoke(() =>
                    {
                        TryFormatJson();
                        _debounceTimer?.Stop();
                    });
                };
                _debounceTimer.AutoReset = false;
            }
            
            _debounceTimer.Stop();
            _debounceTimer.Start();
        }
        
        private void TryFormatJson()
        {
            try
            {
                string inputJson = InputTextBox.Text.Trim();
                if (string.IsNullOrEmpty(inputJson))
                {
                    JsonTreeView.Items.Clear();
                    _currentJsonNode = null;
                    return;
                }

                // Parse and format JSON
                _currentJsonNode = JsonNode.Parse(inputJson);
                
                // Build the tree view
                BuildJsonTreeView();
            }
            catch
            {
                // Silently ignore parsing errors during typing
            }
        }

        private void FormatButton_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                string inputJson = InputTextBox.Text.Trim();
                if (string.IsNullOrEmpty(inputJson))
                {
                    MessageBox.Show("请输入JSON内容进行格式化。", "空输入", MessageBoxButton.OK, MessageBoxImage.Information);
                    return;
                }

                // Use the common format method
                FormatJson(inputJson);
            }
            catch (JsonException ex)
            {
                MessageBox.Show($"无效的JSON: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
            catch (Exception ex)
            {
                MessageBox.Show($"发生错误: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void CopyButton_Click(object sender, RoutedEventArgs e)
        {
            if (!string.IsNullOrEmpty(InputTextBox.Text))
            {
                Clipboard.SetText(InputTextBox.Text);
            }
        }

        private void PasteButton_Click(object sender, RoutedEventArgs e)
        {
            if (Clipboard.ContainsText())
            {
                string clipboardText = Clipboard.GetText();
                InputTextBox.Text = clipboardText;
                
                // Immediately try to format the pasted JSON
                FormatJson(clipboardText);
            }
        }
        
        private void FormatJson(string jsonText)
        {
            try
            {
                string inputJson = jsonText.Trim();
                if (string.IsNullOrEmpty(inputJson))
                {
                    return;
                }

                // Parse and format JSON
                _currentJsonNode = JsonNode.Parse(inputJson);
                string formattedJson = JsonSerializer.Serialize(_currentJsonNode, new JsonSerializerOptions
                {
                    WriteIndented = true
                });

                // Update the input text box with formatted JSON
                InputTextBox.Text = formattedJson;

                // Build the tree view
                BuildJsonTreeView();
            }
            catch
            {
                // Silently ignore parsing errors for invalid JSON
            }
        }

        private void BuildJsonTreeView()
        {
            JsonTreeView.Items.Clear();
            
            if (_currentJsonNode == null)
                return;

            if (_currentJsonNode is JsonObject rootObject)
            {
                TreeViewItem rootItem = new TreeViewItem
                {
                    Header = "Object {}",
                    IsExpanded = true,
                    Tag = _currentJsonNode
                };
                JsonTreeView.Items.Add(rootItem);
                
                foreach (var property in rootObject)
                {
                    AddJsonNodeToTree(rootItem, property.Key, property.Value);
                }
            }
            else if (_currentJsonNode is JsonArray rootArray)
            {
                TreeViewItem rootItem = new TreeViewItem
                {
                    Header = "Array []",
                    IsExpanded = true,
                    Tag = _currentJsonNode
                };
                JsonTreeView.Items.Add(rootItem);
                
                for (int i = 0; i < rootArray.Count; i++)
                {
                    AddJsonNodeToTree(rootItem, i.ToString(), rootArray[i]);
                }
            }
            else
            {
                // Handle primitive value at root (unusual but possible)
                JsonTreeView.Items.Add(new TreeViewItem
                {
                    Header = _currentJsonNode.ToJsonString(),
                    Tag = _currentJsonNode
                });
            }
        }

        private void AddJsonNodeToTree(TreeViewItem parentItem, string key, JsonNode? node)
        {
            if (node == null)
            {
                TreeViewItem nullItem = new TreeViewItem
                {
                    Header = $"{key}: null",
                    Tag = new NodeInfo { Key = key, Node = node, Parent = node?.Parent }
                };
                parentItem.Items.Add(nullItem);
                return;
            }

            if (node is JsonObject obj)
            {
                TreeViewItem objectItem = new TreeViewItem
                {
                    Header = $"{key}: {{}}",
                    IsExpanded = true,
                    Tag = new NodeInfo { Key = key, Node = node, Parent = node.Parent }
                };
                parentItem.Items.Add(objectItem);

                foreach (var property in obj)
                {
                    AddJsonNodeToTree(objectItem, property.Key, property.Value);
                }
            }
            else if (node is JsonArray arr)
            {
                TreeViewItem arrayItem = new TreeViewItem
                {
                    Header = $"{key}: [{arr.Count}]",
                    IsExpanded = true,
                    Tag = new NodeInfo { Key = key, Node = node, Parent = node.Parent }
                };
                parentItem.Items.Add(arrayItem);

                for (int i = 0; i < arr.Count; i++)
                {
                    AddJsonNodeToTree(arrayItem, i.ToString(), arr[i]);
                }
            }
            else
            {
                // Handle primitive values
                string valueStr = node.GetValue<JsonElement>().ValueKind switch
                {
                    JsonValueKind.String => $"\"{node.GetValue<string>()}\"",
                    _ => node.ToJsonString()
                };

                TreeViewItem valueItem = new TreeViewItem
                {
                    Header = $"{key}: {valueStr}",
                    Tag = new NodeInfo { Key = key, Node = node, Parent = node.Parent }
                };
                parentItem.Items.Add(valueItem);
            }
        }

        // Class to store node information
        private class NodeInfo
        {
            public string Key { get; set; } = string.Empty;
            public JsonNode? Node { get; set; }
            public JsonNode? Parent { get; set; }
        }

        private void DeleteNode_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItem? selectedItem = JsonTreeView.SelectedItem as TreeViewItem;
            if (selectedItem == null || selectedItem.Tag == null)
            {
                MessageBox.Show("请选择要删除的节点。", "未选择", MessageBoxButton.OK, MessageBoxImage.Information);
                return;
            }

            try
            {
                // Get node info from the tag
                if (selectedItem.Tag is NodeInfo nodeInfo)
                {
                    // Handle root node deletion
                    if (nodeInfo.Parent == null)
                    {
                        if (_currentJsonNode is JsonObject rootObject && rootObject.ContainsKey(nodeInfo.Key))
                        {
                            rootObject.Remove(nodeInfo.Key);
                        }
                        else if (_currentJsonNode is JsonArray rootArray)
                        {
                            if (int.TryParse(nodeInfo.Key, out int index) && index >= 0 && index < rootArray.Count)
                            {
                                rootArray.RemoveAt(index);
                            }
                        }
                        else
                        {
                            MessageBox.Show("无法删除根节点。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                            return;
                        }
                    }
                    // Handle child node deletion
                    else if (nodeInfo.Parent is JsonObject parentObj)
                    {
                        parentObj.Remove(nodeInfo.Key);
                    }
                    else if (nodeInfo.Parent is JsonArray parentArr)
                    {
                        if (int.TryParse(nodeInfo.Key, out int index) && index >= 0 && index < parentArr.Count)
                        {
                            parentArr.RemoveAt(index);
                        }
                    }
                    else
                    {
                        MessageBox.Show("无法确定父节点类型。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                        return;
                    }

                    // Update the formatted JSON text
                    if (_currentJsonNode != null)
                    {
                        string formattedJson = JsonSerializer.Serialize(_currentJsonNode, new JsonSerializerOptions
                        {
                            WriteIndented = true
                        });
                        InputTextBox.Text = formattedJson;
                        
                        // Rebuild the tree view
                        BuildJsonTreeView();
                    }
                }
                else
                {
                    MessageBox.Show("无效的节点信息。", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
            catch (Exception ex)
            {
                MessageBox.Show($"删除节点失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
            }
        }

        private void CollapseAllNodes_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItem? selectedItem = JsonTreeView.SelectedItem as TreeViewItem;
            if (selectedItem != null)
            {
                CollapseAllSubItems(selectedItem);
            }
        }

        private void ExpandAllNodes_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItem? selectedItem = JsonTreeView.SelectedItem as TreeViewItem;
            if (selectedItem != null)
            {
                ExpandAllSubItems(selectedItem);
            }
        }

        private void ExpandNextLevel_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItem? selectedItem = JsonTreeView.SelectedItem as TreeViewItem;
            if (selectedItem != null)
            {
                selectedItem.IsExpanded = true;
                foreach (TreeViewItem item in selectedItem.Items)
                {
                    item.IsExpanded = false;
                }
            }
        }

        private void CopyNodeContent_Click(object sender, RoutedEventArgs e)
        {
            TreeViewItem? selectedItem = JsonTreeView.SelectedItem as TreeViewItem;
            if (selectedItem != null && selectedItem.Tag is NodeInfo nodeInfo)
            {
                try
                {
                    JsonNode? node = nodeInfo.Node;
                    if (node != null)
                    {
                        string json = JsonSerializer.Serialize(node, new JsonSerializerOptions
                        {
                            WriteIndented = true
                        });
                        Clipboard.SetText(json);
                    }
                }
                catch (Exception ex)
                {
                    MessageBox.Show($"复制节点内容失败: {ex.Message}", "错误", MessageBoxButton.OK, MessageBoxImage.Error);
                }
            }
        }

        private void CollapseAllSubItems(TreeViewItem item)
        {
            item.IsExpanded = false;
            foreach (var subItem in item.Items)
            {
                if (subItem is TreeViewItem treeViewItem)
                {
                    CollapseAllSubItems(treeViewItem);
                }
            }
        }

        private void ExpandAllSubItems(TreeViewItem item)
        {
            item.IsExpanded = true;
            foreach (var subItem in item.Items)
            {
                if (subItem is TreeViewItem treeViewItem)
                {
                    ExpandAllSubItems(treeViewItem);
                }
            }
        }
        
        private void PerformSearch()
        {
            string searchText = SearchTextBox.Text.Trim().ToLower();
            if (string.IsNullOrEmpty(searchText))
                return;
                
            // Clear previous search results
            ClearSearchHighlights();
            _searchResults.Clear();
            _currentSearchIndex = -1;
            
            // Find all matching nodes
            if (JsonTreeView.Items.Count > 0)
            {
                foreach (TreeViewItem item in JsonTreeView.Items)
                {
                    SearchInTreeViewItem(item, searchText);
                }
            }
            
            // Navigate to the first result if any
            if (_searchResults.Count > 0)
            {
                _currentSearchIndex = 0;
                HighlightCurrentSearchResult();
            }
        }
        
        private void SearchInTreeViewItem(TreeViewItem item, string searchText)
        {
            // Check if the current item's header contains the search text
            string header = item.Header.ToString()?.ToLower() ?? "";
            if (header.Contains(searchText))
            {
                _searchResults.Add(item);
            }
            
            // Search in child items
            foreach (var subItem in item.Items)
            {
                if (subItem is TreeViewItem treeViewItem)
                {
                    SearchInTreeViewItem(treeViewItem, searchText);
                }
            }
        }
        
        private void FindNext()
        {
            if (_searchResults.Count == 0)
            {
                PerformSearch();
                return;
            }
            
            // Move to the next result
            _currentSearchIndex = (_currentSearchIndex + 1) % _searchResults.Count;
            HighlightCurrentSearchResult();
        }
        
        private void FindPrevious()
        {
            if (_searchResults.Count == 0)
            {
                PerformSearch();
                return;
            }
            
            // Move to the previous result
            _currentSearchIndex = (_currentSearchIndex - 1 + _searchResults.Count) % _searchResults.Count;
            HighlightCurrentSearchResult();
        }
        
        private void HighlightCurrentSearchResult()
        {
            if (_currentSearchIndex >= 0 && _currentSearchIndex < _searchResults.Count)
            {
                TreeViewItem item = _searchResults[_currentSearchIndex];
                
                // Ensure all parent nodes are expanded
                ExpandParents(item);
                
                // Select and bring into view
                item.IsSelected = true;
                item.BringIntoView();
                
                // Apply highlight style
                item.Background = new SolidColorBrush(Colors.Yellow);
                item.Foreground = new SolidColorBrush(Colors.Black);
            }
        }
        
        private void ExpandParents(TreeViewItem item)
        {
            DependencyObject parent = VisualTreeHelper.GetParent(item);
            while (parent != null)
            {
                if (parent is TreeViewItem parentItem)
                {
                    parentItem.IsExpanded = true;
                }
                parent = VisualTreeHelper.GetParent(parent);
            }
        }
        
        private void ClearSearchHighlights()
        {
            foreach (TreeViewItem item in _searchResults)
            {
                item.ClearValue(TreeViewItem.BackgroundProperty);
                item.ClearValue(TreeViewItem.ForegroundProperty);
            }
        }
    }
}
